package main

/*
#include <stdlib.h>
typedef char* pchar;
typedef unsigned char* puchar;

// 错误码定义
#define KEYAUTH_SUCCESS 0
#define KEYAUTH_ERROR_GENERAL 1

//--------------------------------------------------------------------
// 密钥基础操作
//--------------------------------------------------------------------
int KeyAuthGenerateKeyPair(char* algo, char** pubKey, char** priKey);
int KeyAuthSign(char* algo, char* priKey, void* data, int dataLen,
                void** signature, int* signatureLen);
int KeyAuthVerify(char* algo, char* pubKey, void* data, int dataLen,
                 void* signature, int signatureLen);

//--------------------------------------------------------------------
// 请求数据操作（支持JWT格式）
//--------------------------------------------------------------------
// 支持使用SM2+SM3或ECDSA+SHA256对JWT格式数据进行签名和验证
// 可用于生成和验证会话令牌，替代专用的JWT接口
int KeyAuthSignData(char* priKey, char* headerJson, char* payloadJson,
                   void** signature, int* signatureLen);
int KeyAuthVerifyData(char* pubKey, char* headerJson, char* payloadJson,
                     void* signature, int signatureLen);

//--------------------------------------------------------------------
// 区块链地址操作
//--------------------------------------------------------------------
int KeyAuthGetAddresses(char* pubKey, char* algo, char** addresses);

//--------------------------------------------------------------------
// 区块链合约操作
//--------------------------------------------------------------------
int KeyAuthQuery(char* chainID, char* nodeAddr, int nodePort,
                char* contractName, char* method, char* privateKey,
                char* paramsJSON, char** result);
int KeyAuthInvoke(char* chainID, char* nodeAddr, int nodePort,
                 char* contractName, char* method, char* privateKey,
                 char* paramsJSON, char** result);

//--------------------------------------------------------------------
// 内存管理
//--------------------------------------------------------------------
void KeyAuthFree(void* ptr);
*/
import "C"
import (
	"encoding/json"
	"unsafe"

	"keyauthcore/core"
)

// 初始化全局状态
func init() {
	// 自动初始化库
	core.Initialize()
}

//--------------------------------------------------------------------
// 密钥基础操作 C导出函数
//--------------------------------------------------------------------

//export KeyAuthGenerateKeyPair
func KeyAuthGenerateKeyPair(algo *C.char, pubKey **C.char, priKey **C.char) C.int {
	goAlgo := C.GoString(algo)

	goPubKey, goPriKey, err := core.GenerateKeyPair(goAlgo)
	if err != nil {
		return C.int(1) // KEYAUTH_ERROR_GENERAL
	}

	*pubKey = C.CString(goPubKey)
	*priKey = C.CString(goPriKey)

	return C.int(0) // KEYAUTH_SUCCESS
}

//export KeyAuthSign
func KeyAuthSign(algo *C.char, priKey *C.char, data unsafe.Pointer, dataLen C.int,
	signature *unsafe.Pointer, signatureLen *C.int) C.int {
	goAlgo := C.GoString(algo)
	goPriKey := C.GoString(priKey)
	goData := C.GoBytes(data, dataLen)

	goSignature, err := core.Sign(goPriKey, goAlgo, goData)
	if err != nil {
		return C.int(1) // KEYAUTH_ERROR_GENERAL
	}

	// 分配内存并复制签名
	*signatureLen = C.int(len(goSignature))
	signPtr := C.malloc(C.size_t(len(goSignature)))

	// 手动复制内存
	dest := (*[1 << 30]byte)(signPtr)[:len(goSignature):len(goSignature)]
	copy(dest, goSignature)

	// 设置返回值
	*signature = signPtr

	return C.int(0) // KEYAUTH_SUCCESS
}

//export KeyAuthVerify
func KeyAuthVerify(algo *C.char, pubKey *C.char, data unsafe.Pointer, dataLen C.int,
	signature unsafe.Pointer, signatureLen C.int) C.int {
	goAlgo := C.GoString(algo)
	goPubKey := C.GoString(pubKey)
	goData := C.GoBytes(data, dataLen)
	goSignature := C.GoBytes(signature, signatureLen)

	valid, err := core.Verify(goPubKey, goAlgo, goData, goSignature)
	if err != nil {
		return C.int(1) // KEYAUTH_ERROR_GENERAL
	}

	if valid {
		return C.int(0) // KEYAUTH_SUCCESS
	} else {
		return C.int(1) // KEYAUTH_ERROR_GENERAL
	}
}

//--------------------------------------------------------------------
// 请求数据操作 C导出函数
//--------------------------------------------------------------------

//export KeyAuthSignData
func KeyAuthSignData(priKey *C.char, headerJson *C.char, payloadJson *C.char,
	signature *unsafe.Pointer, signatureLen *C.int) C.int {
	goPriKey := C.GoString(priKey)
	goHeaderJson := C.GoString(headerJson)
	goPayloadJson := C.GoString(payloadJson)

	goSignature, err := core.SignData(goPriKey, goHeaderJson, goPayloadJson)
	if err != nil {
		return C.int(1) // KEYAUTH_ERROR_GENERAL
	}

	// 分配内存并复制签名
	*signatureLen = C.int(len(goSignature))
	signPtr := C.malloc(C.size_t(len(goSignature)))

	// 手动复制内存
	dest := (*[1 << 30]byte)(signPtr)[:len(goSignature):len(goSignature)]
	copy(dest, goSignature)

	// 设置返回值
	*signature = signPtr

	return C.int(0) // KEYAUTH_SUCCESS
}

//export KeyAuthVerifyData
func KeyAuthVerifyData(pubKey *C.char, headerJson *C.char, payloadJson *C.char,
	signature unsafe.Pointer, signatureLen C.int) C.int {
	goPubKey := C.GoString(pubKey)
	goHeaderJson := C.GoString(headerJson)
	goPayloadJson := C.GoString(payloadJson)
	goSignature := C.GoBytes(signature, signatureLen)

	valid, err := core.VerifyData(goPubKey, goHeaderJson, goPayloadJson, goSignature)
	if err != nil {
		return C.int(1) // KEYAUTH_ERROR_GENERAL
	}

	if valid {
		return C.int(0) // KEYAUTH_SUCCESS
	} else {
		return C.int(1) // KEYAUTH_ERROR_GENERAL
	}
}

//--------------------------------------------------------------------
// 区块链地址操作 C导出函数
//--------------------------------------------------------------------

//export KeyAuthGetAddresses
func KeyAuthGetAddresses(pubKey *C.char, algo *C.char, addresses **C.char) C.int {
	goPubKey := C.GoString(pubKey)
	goAlgo := C.GoString(algo)

	// 调用核心函数获取地址
	addrMap, err := core.GetAddresses(goPubKey, goAlgo)
	if err != nil {
		return C.int(1) // KEYAUTH_ERROR_GENERAL
	}

	// 序列化结果为JSON
	resultJSON, err := json.Marshal(addrMap)
	if err != nil {
		return C.int(1) // KEYAUTH_ERROR_GENERAL
	}

	// 返回结果
	*addresses = C.CString(string(resultJSON))

	return C.int(0) // KEYAUTH_SUCCESS
}

//--------------------------------------------------------------------
// 区块链合约操作 C导出函数
//--------------------------------------------------------------------

//export KeyAuthQuery
func KeyAuthQuery(chainID *C.char, nodeAddr *C.char, nodePort C.int,
	contractName *C.char, method *C.char, privateKey *C.char,
	paramsJSON *C.char, result **C.char) C.int {

	// 转换参数
	goChainID := C.GoString(chainID)
	goNodeAddr := C.GoString(nodeAddr)
	goNodePort := int(nodePort)
	goContractName := C.GoString(contractName)
	goMethod := C.GoString(method)
	goPrivateKey := C.GoString(privateKey)
	goParamsJSON := C.GoString(paramsJSON)

	// 解析参数JSON
	var params map[string]string
	if err := json.Unmarshal([]byte(goParamsJSON), &params); err != nil {
		return C.int(1) // KEYAUTH_ERROR_GENERAL
	}

	// 创建链客户端
	client, err := core.NewChainClient(goChainID, goNodeAddr, goNodePort)
	if err != nil {
		return C.int(1) // KEYAUTH_ERROR_GENERAL
	}
	defer client.Close()

	// 查询合约
	contractResult, err := client.Query(goContractName, goMethod, goPrivateKey, params)
	if err != nil {
		return C.int(1) // KEYAUTH_ERROR_GENERAL
	}

	// 序列化结果
	resultJSON, err := json.Marshal(contractResult)
	if err != nil {
		return C.int(1) // KEYAUTH_ERROR_GENERAL
	}

	// 返回结果
	*result = C.CString(string(resultJSON))

	return C.int(0) // KEYAUTH_SUCCESS
}

//export KeyAuthInvoke
func KeyAuthInvoke(chainID *C.char, nodeAddr *C.char, nodePort C.int,
	contractName *C.char, method *C.char, privateKey *C.char,
	paramsJSON *C.char, result **C.char) C.int {

	// 转换参数
	goChainID := C.GoString(chainID)
	goNodeAddr := C.GoString(nodeAddr)
	goNodePort := int(nodePort)
	goContractName := C.GoString(contractName)
	goMethod := C.GoString(method)
	goPrivateKey := C.GoString(privateKey)
	goParamsJSON := C.GoString(paramsJSON)

	// 解析参数JSON
	var params map[string]string
	if err := json.Unmarshal([]byte(goParamsJSON), &params); err != nil {
		return C.int(1) // KEYAUTH_ERROR_GENERAL
	}

	// 创建链客户端
	client, err := core.NewChainClient(goChainID, goNodeAddr, goNodePort)
	if err != nil {
		return C.int(1) // KEYAUTH_ERROR_GENERAL
	}
	defer client.Close()

	// 调用合约
	contractResult, err := client.Invoke(goContractName, goMethod, goPrivateKey, params)
	if err != nil {
		return C.int(1) // KEYAUTH_ERROR_GENERAL
	}

	// 序列化结果
	resultJSON, err := json.Marshal(contractResult)
	if err != nil {
		return C.int(1) // KEYAUTH_ERROR_GENERAL
	}

	// 返回结果
	*result = C.CString(string(resultJSON))

	return C.int(0) // KEYAUTH_SUCCESS
}

//--------------------------------------------------------------------
// 内存管理 C导出函数
//--------------------------------------------------------------------

//export KeyAuthFree
func KeyAuthFree(ptr unsafe.Pointer) {
	// 统一的内存释放函数
	if ptr != nil {
		C.free(ptr)
	}
}

func main() {
	// 这个函数不会被执行，但必须存在
}
